<template>
    <el-dialog v-model="show" title="条码打印" width="500" :before-close="handleClose">
        打印服务状态：{{ !printSocketOpen ? "未" : "已" }}连接
        <div class="select_usb">
            <div class="select_printer status">
                <label>选择USB打印机:</label>
                <select v-model="usbSelectPrinter" name="usbPrinters">
                    <option value="" disabled v-if="!Object.keys(usbPrinters).length">
                        请选择USB打印机
                    </option>

                    <option v-for="(value, name) in usbPrinters" :value="name" :key="name">
                        {{ name }}: {{ value }}
                    </option>
                </select>
            </div>
            <el-button type="primary" class="getPrinters" @click="getPrinters()">
                更新USB打印机列表
            </el-button>
        </div>
        <div class="connect_usb">
            <div>
                <label class="usb_printer_connect_status status">
                    打印机连接状态：USB打印机{{ !onlineUsbBool ? "未" : "已" }}连接
                </label>
            </div>

            <el-button type="primary" class="connect_printer" @click="selectOnLineUsbPrinter()">
                连接USB打印机
            </el-button>
        </div>
        <div class="init">
            <div class="init_content">
                <div>
                    <label class="init_status status">
                        SDK初始化状态：{{ !initBool ? "未" : "已" }}初始化
                    </label>
                </div>
                <el-button type="primary" class="init_sdk status" @click="init()">
                    初始化SDK
                </el-button>
            </div>
        </div>
        <svg ref="barcodeRef"></svg>
        <template #footer>
            <div class="dialog-footer">
                <el-button @click="cancel">取 消</el-button>
                <el-button type="primary" @click="submitForm">打 印</el-button>
            </div>
        </template>
        <el-dialog v-model="dialogFlag" title="条码打印" width="400" :before-close="dialogCancel">
            <el-form :model="queryParams" ref="queryFormRef" label-position="top" label-width="120px" :rules="rules">
                <el-form-item label="请输入打印数量" prop="nums">
                    <el-input-number v-model="queryParams.nums" :min="1" :max="99" placeholder="请输入打印数量" clearable
                        @keyup.enter="dialogSubmitForm" style="width: 240px" />
                </el-form-item>
            </el-form>
            <template #footer>
                <div class="dialog-footer">
                    <el-button :loading="buttonLoading" type="primary" @click="dialogSubmitForm">确认打印</el-button>
                </div>
            </template>
        </el-dialog>
    </el-dialog>
</template>
<script setup name="Printing" lang="ts">
import JsBarcode from 'jsbarcode'
import Socket from "@/utils/socket";
import NMPrintSocket from "@/utils/print";

// 打印服务状态
const printSocketOpen = ref<boolean>(false)
// 选择USB打印机
const usbSelectPrinter = ref<string>('')
// 打印机数组
const usbPrinters = ref<{ [key: string]: any }>({})
// 打印机连接状态
const onlineUsbBool = ref(false)
// 打印实例
const nMPrintSocket = ref<any>(null)
// 初始化SDK
const initBool = ref<boolean>(false)
// 打印数量
const jsonObj = ref({
    printerImageProcessingInfo: {
        printQuantity: 1
    }
})
// 打印浓度 常量
const density = 3
// 纸张类型 常量
const label_type = 1
// 打印模式 常量
const print_mode = 1


var offsetX = 0;
var offsetY = 0;
var width = 40;
var height = 20;
var rotate = 0;
var marginX = 2.0;
var marginY = 2.0;
var barCodeWidth = width - marginX * 2;
var barCodeHeight = height - marginY * 2;
var fontSize = 3.2;
//文本打印数据
const barcodePrintData = ref({
    InitDrawingBoardParam: {
        width: width,
        height: height,
        rotate: rotate,
        path: "ZT001.ttf",
        verticalShift: 0,
        HorizontalShift: 0,
    },

    elements: [
        {
            type: "barCode",
            json: {
                x: marginX + offsetX,
                y: marginY + offsetY,
                height: barCodeHeight,
                width: barCodeWidth,
                value: "",
                codeType: 20,
                rotate: 0,
                fontSize: fontSize,
                textHeight: fontSize,
                textPosition: 0,
            },
        },
    ],
})



const buttonLoading = ref(false);
const queryParams = ref({
    nums: 1
})
const rules = ref({
    nums: [
        { required: true, message: "请输入打印数量", trigger: "blur" }
    ]
})
const queryFormRef = ref<ElFormInstance>()
const dialogFlag = ref(false)
// 一维码生成默认字段 常量
const options = {
    // format: 'EAN13', // 格式
    height: 50,
    // text: "覆盖显示的文本",
    fontSize: 16,
    // background: '#ccc',
    lineColor: 'black'
}
const props = defineProps({
    printingVisible: {
        type: Boolean,
        default: false
    },
    printingNumber: {
        type: String,
        default: false
    }
});
const show = computed(() => props.printingVisible);
const emits = defineEmits(['doClose'])
const handleClose = () => {
    emits('doClose')
}

const barcodeRef = ref(null)
watch(() => props.printingNumber, async (val: string) => {
    if (val) {
        await nextTick();
        console.log(barcodeRef.value)
        JsBarcode(barcodeRef.value, val, options)

    }
})


//更新打印机列表
const getPrinters = async () => {
    if (!printSocketOpen.value) {
        return alert("打印服务未开启");
    }
    console.log("开始获取打印机");
    try {
        const allPrintersRes = await nMPrintSocket.value.getAllPrinters();
        console.log(allPrintersRes, "allPrintersRes");
        if (allPrintersRes.resultAck.errorCode === 0) {
            const allPrinters = JSON.parse(allPrintersRes.resultAck.info);
            usbPrinters.value = { ...allPrinters };
            usbSelectPrinter.value = Object.keys(usbPrinters.value)[0];
            console.log("printers", usbPrinters.value);
        } else {
            alert("没有在线的打印机");
        }
    } catch (err) {
        console.error(err);
    }
}
const selectOnLineUsbPrinter = async () => {
    if (!printSocketOpen.value) {
        return alert("打印服务未开启");
    }
    console.log("开始连接打印机");
    try {
        console.log(usbSelectPrinter.value)
        console.log(usbPrinters.value)
        const res = await nMPrintSocket.value.selectPrinter(
            usbSelectPrinter.value,
            parseInt(usbPrinters.value[usbSelectPrinter.value])
        );
        console.log("选择打印机", res);

        if (res.resultAck.errorCode === 0) {
            console.log("连接成功");
            onlineUsbBool.value = true;
        } else {
            console.log("连接失败");
            onlineUsbBool.value = false;
            alert("连接失败");
        }
    } catch (err) {
        console.error(err);
    }
}
//初始化SDK
const init = async () => {
    if (!printSocketOpen.value) {
        return alert("打印服务未开启")
    }
    //初始化数据
    try {
        const res = await nMPrintSocket.value.initSdk({ fontDir: "" });
        if (res.resultAck.errorCode == 0) {
            console.log("初始化成功");
            initBool.value = true;
        } else {
            console.log("初始化失败");
            initBool.value = false;
        }
    } catch (err) {
        console.error(err);
    }
}
onMounted(() => {
    // 创建socket实例
    const socketData = new Socket("ws://127.0.0.1:37989");
    socketData.open(
        (openBool: boolean) => {
            console.log(openBool, "openBool");
            printSocketOpen.value = openBool;
        },
        (msg: any) => {
            if (msg.resultAck.callback != undefined) {
                const callbackName = msg.resultAck.callback.name;
                const msgInfo = msg.resultAck.info;
                if (callbackName == "onCoverStatusChange") {
                    //盒盖状态：0-闭合、1-打开
                    console.log("盒盖状态", msgInfo.capStatus);
                } else if (callbackName == "onElectricityChange") {
                    //"power" : 0-4, // 电池电量等级（共5档）
                    console.log("电池电量等级", msgInfo.power);
                }
            }
        }
    );
    // 创建打印实例
    nMPrintSocket.value = new NMPrintSocket(socketData);
})
/** 取消按钮 */
const cancel = () => {
    handleClose()
}

/** 提交按钮 */
const submitForm = () => {
    dialogFlag.value = true
}
const dialogCancel = () => {
    dialogFlag.value = false
}
const dialogSubmitForm = () => {
    queryFormRef.value?.validate(async (valid: boolean) => {
        if (valid) {
            // 一维码码值
            barcodePrintData.value.elements[0].json.value = props.printingNumber
            // 数量
            jsonObj.value.printerImageProcessingInfo.printQuantity = queryParams.value.nums
            console.log(barcodePrintData.value)
            console.log(jsonObj.value.printerImageProcessingInfo.printQuantity)
            startPrintJobTest(barcodePrintData.value)
        }
    })
}
// 开始打印
const startPrintJobTest = async (content: any) => {
    if (!printSocketOpen.value) return alert("打印服务未开启");
    let contentArr = [];
    contentArr.push(content);
    batchPrintJob(contentArr);
}
//批量打印列表数据
const batchPrintJob = async (list: any) => {
    const printQuantity =
        jsonObj.value.printerImageProcessingInfo.printQuantity;
    try {
        const startRes = await nMPrintSocket.value.startJob(
            density,
            label_type,
            print_mode,
            list.length * printQuantity
        );
        if (startRes.resultAck.errorCode == 0) {
            // 提交打印任务
            await printTag(list, 0);
        }
    } catch (err) {
        console.error(err);
    }
}
// 绘制打印标签
const printTag = async (list: any, x: number) => {
    console.log(list, x);
    //设置画布尺寸
    try {
        const res = await nMPrintSocket.value.InitDrawingBoard(
            list[x].InitDrawingBoardParam
        );
        if (res.resultAck.errorCode != 0) {
            return;
        }
        // 提交打印任务
        printItem(list, x, list[x].elements, 0);
    } catch (err) {
        console.error(err);
    }
}
const printItem = async (list: any, x: number, item: any, i: number) => {
    try {
        if (i < item.length) {
            let arrParse;
            switch (item[i].type) {
                case "barCode":
                    //绘制一维码
                    arrParse = await nMPrintSocket.value.DrawLableBarCode(
                        item[i].json
                    );
                    if (arrParse.resultAck.errorCode !== 0) {
                        return;
                    }
                    i++;
                    await printItem(list, x, item, i);
                    break;
            }
        } else {
            //遍历完成，开始打印
            const commitRes = await nMPrintSocket.value.commitJob(
                null,
                JSON.stringify(jsonObj.value)
            );
            //回调页码为数据总长度且回调打印份数数据等于当前页需要打印的份数数据时，结束打印任务
            if (
                commitRes.resultAck.printQuantity == list.length && commitRes.resultAck.onPrintPageCompleted == jsonObj.value.printerImageProcessingInfo.printQuantity
            ) {
                //结束打印任务
                const endRes = await nMPrintSocket.value.endJob();
                if (endRes.resultAck.errorCode === 0) {
                    console.log("打印完成");
                }
                return;
            }
            //回调为提交成功，同时数据未发送完成时，可继续提交数据
            if (commitRes.resultAck.errorCode === 0 && x < list.length - 1) {
                //数据提交成功，数据下标+1
                console.log("发送下一页打印数据： ");
                x++;
                await printTag(list, x);
            }
        }
    } catch (err) {
        console.error(err);
    }
}
</script>
<style lang="scss" scoped></style>